package com.charging.business.vo.obj;

import com.alibaba.fastjson2.annotation.JSONField;
import com.charging.business.gantry.EntryFeeCalcResponse;
import com.charging.business.media.CpcEf04Model;
import com.charging.business.media.CpcProvModel;
import com.charging.common.utils.DateUtils;
import com.charging.common.utils.StringUtils;

import java.util.*;

/**
 * @author JerryLu
 * @date 2024/9/26 17:12
 * @description 出口CPC计费信息
 */
public class CpcFeeInfo {
    /**
     * 总应收金额, 单位：分(预留)
     * 必填：否
     */
    @JSONField(ordinal = 0)
    public Integer payFee = 0;

    /**
     * 总优惠金额, 单位：分(预留)
     * 必填：否
     */
    @JSONField(ordinal = 1)
    public Integer discountFee = 0;

    /**
     * 总实收金额, 单位：分
     * 必填：是
     */
    @JSONField(ordinal = 2)
    public Integer fee = 0;

    /**
     * 总里程
     * 必填：是
     */
    @JSONField(ordinal = 3)
    public Integer feeMileage = 0;

    /**
     * 分省金额明细
     * 必填：
     */
    @JSONField(ordinal = 4)
    public List<SplitProvinceCpc> splitProvince = new ArrayList<>();

    /**
     * 计费模块输出
     * 必填：
     */
    @JSONField(ordinal = 5)
    public FeeInfo feeInfo = new FeeInfo();

    /**
     * 自定义字段
     * true -  为多省
     * false - 为单省
     */
    @JSONField(ordinal = 6, serialize = false, deserialize = false)
    public boolean zMultiProvinces = false;

    /**
     * 过省数量
     * 自定义字段
     */
    @JSONField(ordinal = 7, serialize = false, deserialize = false)
    public Integer zProvinceCount = 0;

    /**
     * 设置前序行程
     *
     * @param count     - 行程数(CPCDFEF02内的过省数量)
     * @param ef04Model - CPC卡内DFEF04文件
     * @param enStationHex - 入口收费站hex
     */
    @JSONField(serialize = false, deserialize = false)
    public void setPrevTrip(int count, CpcEf04Model ef04Model, String enStationHex) {
        fee = 0;
        payFee = 0;
        discountFee = 0;
        feeMileage = 0;
        splitProvince.clear();

        // 正常不含最后段行程(有新行程时需要含最后一段行程)
        for (int aa = 0; aa < count - 1; aa++) {
            CpcProvModel prov = ef04Model.provInfos[aa];

            payFee += prov.provSumPayFee;
            fee += prov.provSumPayFee;
            feeMileage += prov.sumMileage;

            SplitProvinceCpc sp = new SplitProvinceCpc();
            sp.provinceId = Integer.parseInt(prov.provinceId);
            if ("000000".equals(prov.provEntryHex)) {
                sp.enPointId = enStationHex;
                sp.enTollStationName = enStationHex;
            } else {
                sp.enPointId = prov.provEntryHex;
                sp.enTollStationName = prov.provEntryHex;
            }
            sp.exPointId = prov.newGantryNo;
            sp.exTollStationName = prov.newGantryNo;
            sp.enTime = DateUtils.convertTimestampT(prov.enTime);
            sp.exTime = DateUtils.convertTimestampT(prov.newGantryTime);
            sp.feeMileage = prov.sumMileage;
            sp.tollPayFee = prov.provSumPayFee;
            sp.tollFee = prov.provSumPayFee;

            splitProvince.add(sp);
        }

        discountFee = payFee - fee;
    }

    /**
     * 添加最后行程(本省)
     *
     * @param rsp
     * @param exTime
     * @param provinceId
     * @param ef04Model
     * @param enStationHex
     */
    public void addLastTrip(EntryFeeCalcResponse rsp, Date exTime, int provinceId, CpcEf04Model ef04Model, int count, String enStationHex) {
        //前序行程+最后一次行程
        fee += rsp.getFeeSpare1();
        //前序行程+最后一次行程
        payFee += rsp.getFeeProvSumLocal();
        //总优惠
        discountFee = payFee - fee;
        //前序行程+最后一次行程
        feeMileage += rsp.getFeeSpare2();
        //总优惠校验
        if (discountFee < 0) {
            payFee = fee;
            discountFee = 0;
        }

        SplitProvinceCpc sp = new SplitProvinceCpc();
        sp.provinceId = provinceId;
        CpcProvModel model = ef04Model.lastProv(count);
        if (StringUtils.isNotEmpty(rsp.getFeeProvBeginHexFit())) {
            sp.enPointId = rsp.getFeeProvBeginHexFit();
            sp.enTollStationName = rsp.getFeeProvBeginHexFit();
        } else {
            if (model != null) {
                if ("000000".equals(model.provEntryHex)) {
                    sp.enPointId = enStationHex;
                    sp.enTollStationName = enStationHex;
                } else {
                    sp.enPointId = model.provEntryHex;
                    sp.enTollStationName = model.provEntryHex;
                }
            }
        }

        if (StringUtils.isNotEmpty(rsp.getFeeProvBeginTimeFit())) {
            sp.enTime = rsp.getFeeProvBeginTimeFit();
        } else {
            if (model != null) {
                sp.enTime = DateUtils.convertTimestampT(model.enTime);
            }
        }
        if (StringUtils.isNotEmpty(rsp.getGantryPassHexFit())) {
            sp.exPointId = rsp.getGantryPassHexFit();
            sp.exTollStationName = rsp.getGantryPassHexFit();
        } else {
            if (model != null) {
                sp.exPointId = model.newGantryNo;
                sp.exTollStationName = model.newGantryNo;
            }
        }
        sp.exTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_TT_HH_MM_SS, exTime);
        sp.feeMileage = rsp.getFeeSpare2();
        sp.tollPayFee = rsp.getFeeProvSumLocal();
        sp.tollFee = rsp.getFeeSpare1();
        sp.tollDiscountFee = sp.tollPayFee - sp.tollFee;
        if (sp.tollDiscountFee < 0) {
            sp.tollPayFee = sp.tollFee;
            sp.tollDiscountFee = 0;
        }

        splitProvince.add(sp);

        feeInfo.rateVersion = rsp.getParamVersion();                //计费模块和计费参数版本号
        feeInfo.feeVehicleType = rsp.getFeeVehicleType();           //计费车型
        feeInfo.feeMileage = rsp.getFeeMileage();                   //拟合计费里程
        feeInfo.payFee = rsp.getPayFee();                           //拟合应收
        feeInfo.realFee = rsp.getRealFee();                         //拟合实收
        feeInfo.cardFee = rsp.getCardFee();                         //ETC最终卡面扣款金额(复合消费金额)
        feeInfo.discountFee = rsp.getDiscountFee();                 //拟合优惠
        feeInfo.tollIntervalIDs = rsp.getTollInterValIds();         //拟合收费单元组
        feeInfo.payFeeGroup = rsp.getPayFeeGroup();                 //拟合应收组
        feeInfo.feeGroup = rsp.getFeeGroup();                       //拟合实收组
        feeInfo.discountFeeGroup = rsp.getDiscountFeeGroup();       //拟合优惠组
        feeInfo.feeSpare2 = rsp.getFeeSpare2();                     //本省累计里程
        feeInfo.feeSpare1 = rsp.getFeeProvSumLocal();               //本省累计应收
        feeInfo.feeProvSumLocal = rsp.getFeeSpare1();               //本省累计实收
        feeInfo.provMinFee = rsp.getProvMinFee();                   //本省最小费额
        feeInfo.feeCalcSpecials = rsp.getFeeSpecial();              //计费特情组合
        feeInfo.pathFitFlag = rsp.getFitResult();                   //拟合结果
        feeInfo.feeInfo1 = rsp.getFeeInfo1();
        feeInfo.feeInfo2 = rsp.getFeeInfo2();
        feeInfo.feeInfo3 = rsp.getFeeInfo3();
        feeInfo.feeLogMsg = rsp.getFeeLogMsg();
        feeInfo.feeSpare3 = rsp.getFeeSpare3();
        feeInfo.feeProvBeginHexFit = rsp.getFeeProvBeginHexFit();   //拟合本省入口
        feeInfo.feeProvBeginTimeFit = rsp.getFeeProvBeginTimeFit(); //拟合本省入口时间
        if (rsp.getFitProvFlag() == 0) {
            feeInfo.fitProvFlag = 0;
            feeInfo.gantryPassNumFit = 0;
            feeInfo.gantryPassHexFit = "";
        } else {
            feeInfo.fitProvFlag = rsp.getFitProvFlag();
            feeInfo.gantryPassNumFit = rsp.getGantryPassNumFit();
            feeInfo.gantryPassHexFit = rsp.getGantryPassHexFit();
        }
    }

    /**
     * 合并分省信息
     */
    public void merge() {
        if (splitProvince.size() > 1) {
            Map<Integer, SplitProvinceCpc> provs = new LinkedHashMap<>();

            for (SplitProvinceCpc src : splitProvince) {
                SplitProvinceCpc mer = provs.get(src.provinceId);
                if (mer == null) {
                    provs.put(src.provinceId, src);
                } else {
                    mer.enPointId = src.enPointId;
                    mer.exPointId = src.exPointId;
                    mer.enTollStationName = src.enTollStationName;
                    mer.exTollStationName = src.exTollStationName;
                    mer.enTime = src.enTime;
                    mer.exTime = src.exTime;
                    mer.feeMileage += src.feeMileage;
                    mer.tollPayFee += src.tollPayFee;
                    mer.tollDiscountFee += src.tollDiscountFee;
                    mer.tollFee += src.tollFee;
                }
            }

            splitProvince.clear();
            for (Integer key : provs.keySet()) {
                splitProvince.add(provs.get(key));
            }
        }
    }

    /**
     * 绿通、联合收割机免费处理
     * 分省信息保持不变
     */
    public void green() {
        fee = 0;
        discountFee = payFee;
    }

    /**
     * 全免费,清除计费信息
     */
    public void toAllFree() {
        fee = 0;
        discountFee = payFee;

        for (SplitProvinceCpc prov : splitProvince) {
            prov.toFree();
        }
    }

    /**
     * 本省免费,清除本省计费信息
     */
    public void toLocalFree() {
        fee = 0;
        for (SplitProvinceCpc prov : splitProvince) {
            if (prov.provinceId == 14) {// 本省免费
                prov.toFree();
            }
            fee += prov.tollFee;
        }
        discountFee = payFee - fee;
    }

    /**
     * 获取本省免费后实收金额
     * 用于进行阈值比较
     *
     * @return
     */
    public int mtcFeeAfterLocalFree() {
        int res = 0;
        for (SplitProvinceCpc prov : splitProvince) {
            if (prov.provinceId != 14) {// 外省
                res += prov.tollFee;
            }
        }
        return res;
    }

    /**
     * 获取本省累计应收
     *
     * @return
     */
    public int payFeeProvSumLocal() {
        int res = 0;
        for (SplitProvinceCpc prov : splitProvince) {
            if (prov.provinceId == 14) {// 本省
                res += prov.tollPayFee;
            }
        }

        return res;
    }

    /**
     * 获取本省累计实收
     *
     * @return
     */
    public int feeProvSumLocal() {
        int res = 0;
        for (SplitProvinceCpc prov : splitProvince) {
            if (prov.provinceId == 14) {// 本省
                res += prov.tollFee;
            }
        }

        return res;
    }

    /**
     * 获取本省累计里程
     *
     * @return
     */
    public int feeMileageProvSumLocal() {
        int res = 0;
        for (SplitProvinceCpc prov : splitProvince) {
            if (prov.provinceId == 14) {// 本省
                res += prov.feeMileage;
            }
        }

        return res;
    }
}
